parser grammar BlipParser;

options {
  language = Java;
  tokenVocab = BlipLexer;
  output = AST;
}

// List of tokens used to structure the tree
tokens {
  APPLICATION;
  ATTR;
  MODEL;
  MODEL_ATTR;
  SERVICE;
  T;
  ATTRIBUTE;
}

@members {
  public Collection<Problem> problems = new ArrayList<Problem>();

      public void displayRecognitionError(String[] tokenNames,
                                        RecognitionException e) {
          Problem problem = MocaFactory.eINSTANCE.createProblem();
          int line  = e.line;
          int charPos = e.charPositionInLine;
          int tokenLenght = 1;
          Token token = e.token;
          if(token != null) 
            tokenLenght = token.getText().length();
                  
          
          problem.setType(ProblemType.ERROR);
          problem.setLine(line); 
          problem.setCharacterPositionStart(charPos); 
          problem.setCharacterPositionEnd(charPos+tokenLenght);
          problem.setMessage("Parser: " + getErrorMessage(e, tokenNames));
          
          problems.add(problem);
          super.displayRecognitionError(tokenNames, e);
    }
}

@header {
package org.moflon.moca.blip.parser; 
import java.util.Collection;
import Moca.MocaFactory;
import Moca.Problem;
import Moca.ProblemType;
}

// Parser Rules:
// Parser Rules:
main: applicationPart+
	-> ^(T["Application"] applicationPart+);

applicationPart: attribute -> attribute | model -> model | service -> service;

attribute: AT name=STRING value=STRING
	-> ^(ATTRIBUTE $name $value);

model: MINUS name=STRING LBRACE modelAttr* RBRACE
	-> ^(T["Model"] ^(ATTRIBUTE T["name"] $name) modelAttr*);

modelAttr: name=STRING COLON type=STRING (isArray=BRACKETS)?
	-> ^($name ^(ATTRIBUTE T["type"] $type));
	
service: type=SERVICETYPE name=STRING attribute* LBRACE servicePart* RBRACE 
	-> ^(SERVICE $type attribute* servicePart*);

servicePart: modelAttr;